/**
  ETFDAQ Project -- online from ETFAna Online by SUN Yazhou
  \struct online_shm_pxi
  \brief vme online structure defined by S.T. Wang for TA
  \author SUN Yazhou, asia.rabbit@163.com
  \since 2023-07-07
  \date 2023-07-07 last modified
  \attention
  changelog
  <table>
  <tr>  <th>Date         <th>Author      <th>Description                    </tr>
  <tr>  <td>2023-07-07   <td>Asia Sun    <td>file created                   </tr>
  </table>

  \copyright Copyright (c) 2021-2024 Anyang Normal U. && IMP-CAS with LGPLv3 LICENSE
*/

#ifndef online_shm_h
#define online_shm_h

#include <semaphore.h>
#include <cstring>
#include <string>
#include <cstdio>

using std::string;

/// DO NOT CHANGE THE ORDER OF THE MEMBER VARIABLES !!!
struct online_shm{
  static const size_t MAX_STRING_LEN = 128;

  char name[MAX_STRING_LEN];
  sem_t mutex, nempty, nstored;
  int p_write, p_read;

  ~online_shm(){}
};

struct online_shm_pxi : online_shm{
  // HAS TO BE THE SAME AS THE DAQ CODE //
  static constexpr size_t MAX_LEN = 8192;
  static constexpr size_t MAX_NUM = 5000;
  int section[MAX_NUM][MAX_LEN];

  online_shm_pxi() : online_shm(){}

  void initialize(const char *name_ = ""){
    strcpy(name, name_);
    if(-1 == sem_init(&nempty, 1, MAX_NUM))
      perror("online_shm_pxi::initialize: sem_init error, ");
    if(-1 == sem_init(&nstored, 1, 0)) perror("online_shm_pxi::initialize: sem_init error");
    p_write = p_read = 0;
    memset(section, 0, sizeof(section));
    // please initialize mutex in the last line - used in reinit mode //
    if(-1 == sem_init(&mutex, 1, 1)) perror("online_shm_pxi::initialize: sem_init error");
  } // end member function initialize
};

struct online_shm_vme : online_shm{
  // HAS TO BE THE SAME AS THE DAQ CODE //
  static constexpr size_t MAX_NUM = 5000;
  static constexpr size_t MAX_LEN = 2000;
  int section[MAX_NUM][MAX_LEN]{};

  online_shm_vme() : online_shm(){}

  void initialize(const char *name_ = ""){
    strcpy(name, name_);
    if(-1 == sem_init(&nempty, 1, MAX_NUM))
      perror("online_shm_vme::initialize: sem_init error, ");
    if(-1 == sem_init(&nstored, 1, 0)) perror("online_shm_vme::initialize: sem_init error");
    p_write = p_read = 0;
    memset(section, 0, sizeof(section));
    // please initialize mutex in the last line - used in reinit mode //
    if(-1 == sem_init(&mutex, 1, 1)) perror("online_shm_vme::initialize: sem_init error");
  } // end member function initialize
};

#endif
